package com.gdziarmaga.webshop.web.managedBeans.client;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.event.ValueChangeEvent;
import javax.servlet.http.Cookie;

import org.springframework.beans.factory.annotation.Autowired;

import com.gdziarmaga.webshop.book.model.Book;
import com.gdziarmaga.webshop.book.model.BookShortInfo;
import com.gdziarmaga.webshop.book.services.BookManager;
import com.gdziarmaga.webshop.client.model.BookClient;
import com.gdziarmaga.webshop.client.model.Client;
import com.gdziarmaga.webshop.client.services.ClientManager;
import com.gdziarmaga.webshop.login.model.Login;
import com.gdziarmaga.webshop.login.services.LoginManager;
import com.gdziarmaga.webshop.transaction.model.Transaction;
import com.gdziarmaga.webshop.transaction.model.TransactionBook;
import com.gdziarmaga.webshop.transaction.services.TransactionManager;
import com.gdziarmaga.webshop.utils.springcontext.AppContext;
import com.gdziarmaga.webshop.web.utils.FacesUtils;

@SessionScoped
@ManagedBean(name = "basketBean")
public class BasketBean implements Serializable {

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 3335815676096621193L;

	@Autowired
	private BookManager bookManager;

	@Autowired
	private ClientManager clientManager;

	@Autowired
	private LoginManager loginManager;

	@Autowired
	private TransactionManager transactionManager;

	private List<BookClient> book_list;

	private float price = 0;

	@PostConstruct
	public void init() {
		bookManager = (BookManager) AppContext.getApplicationContext().getBean(
				"bookManager");
		clientManager = (ClientManager) AppContext.getApplicationContext()
				.getBean("clientManager");
		loginManager = (LoginManager) AppContext.getApplicationContext()
				.getBean("loginManager");
		transactionManager = (TransactionManager) AppContext
				.getApplicationContext().getBean("transManager");
	}

	public List<BookClient> getBook_list() {
		if (book_list == null) {
			book_list = new ArrayList<BookClient>();
			ClientLoginBean bean = ((ClientLoginBean) FacesUtils.getRequest()
					.getSession().getAttribute("clientLoginBean"));
			if (bean.isLogged()) {
				List<BookClient> bookClients = clientManager
						.getBooksOfClient(bean.getClient());
				getBook_list().clear();
				getBook_list().addAll(bookClients);
			} else {
				Cookie[] cookies = FacesUtils.getRequest().getCookies();
				if (cookies != null) {
					for (int i = 0; i < cookies.length; i++) {
						if (cookies[i].getName().equalsIgnoreCase("books")) {
							String cookieValue = cookies[i].getValue();
							parseCookieBookList(cookieValue);

						}
					}
				}
			}
		}
		return book_list;
	}

	private void parseCookieBookList(String cookie) {
		StringBuilder string = new StringBuilder(cookie);
		
		if(string.length()>2){
		String tail = string.substring(1, cookie.length() - 2);

		String[] table = tail.split("\\|");
		for (int i = 0; i < table.length; i++) {
			BookClient bookClient = new BookClient();
			bookClient.setBook(bookManager.getBookById(Long.decode(table[i]
					.split("\\,")[0])));
			bookClient.setClient(new Client());
			bookClient
					.setBooks_in_basket(Integer.decode((table[i].split("\\,")[1])));
			getBook_list().add(bookClient);
		}
	}
	}

	public void addBook(AjaxBehaviorEvent event) {
		BookShortInfo bookShortInfo = (BookShortInfo) event.getComponent()
				.getAttributes().get("book");
		Book book = bookManager.getBookById(bookShortInfo.getBook_id());
		ClientLoginBean clientLoginBean = (ClientLoginBean) FacesUtils
				.getRequest().getSession().getAttribute("clientLoginBean");
		Client client = null;
		BookClient bookClient = null;
		if (clientLoginBean.isLogged()) {
			if (checkIfBookExistInCart(book)) {
				for (BookClient object : getBook_list()) {
					if (object.equals(book)) {
						object.setBooks_in_basket(object.getBooks_in_basket() + 1);
						clientManager.saveClientBook(object);
					}

				}
			} else {
				client = clientLoginBean.getClient();
				bookClient = new BookClient();
				bookClient.setBook(book);
				bookClient.setClient(client);
				bookClient.setBooks_in_basket(1);
				getBook_list().add(bookClient);
				clientManager.saveClientBook(bookClient);
			}
		} else {
			if (checkIfBookExistInCart(book)) {
				for (BookClient object : getBook_list()) {
					if (object.getBook().equals(book)) {
						object.setBooks_in_basket(object.getBooks_in_basket() + 1);
					}
				}
			} else {
				client = new Client();
				bookClient = new BookClient();
				bookClient.setBook(book);
				bookClient.setClient(client);
				bookClient.setBooks_in_basket(1);
				getBook_list().add(bookClient);
			}
			createBookCookie();
		}

	}

	private boolean checkIfBookExistInCart(Book book) {
		for (BookClient bookClient : getBook_list()) {
			if (bookClient.getBook().equals(book))
				return true;
		}
		return false;
	}

	private void createBookCookie() {
		Cookie cookie = new Cookie("books", createCookieBookList());
		cookie.setPath("/");
		cookie.setMaxAge(60 * 60 * 24 * 365);
		FacesUtils.getResponse().addCookie(cookie);
	}

	private String createCookieBookList() {
		StringBuilder string = new StringBuilder();
		string.append("{");
		for (BookClient bookClient : getBook_list()) {
			string.append(bookClient.getBook().getBook_id() + ","
					+ bookClient.getBooks_in_basket() + "|");
		}
		string.append("}");
		return string.toString();
	}

	public void removeBook(AjaxBehaviorEvent event) {
		getBook_list().remove(
				(BookClient) event.getComponent().getAttributes().get("book"));
		createBookCookie();
	}

	public float getPrice() {
		price = 0;
		for (BookClient bookClient : getBook_list()) {
			price += bookClient.getBooks_in_basket()
					* bookClient.getBook().getPrice();
		}
		return price;
	}

	public void confirmOrder(ActionEvent event) {
		ClientLoginBean clientLoginBean = ((ClientLoginBean) FacesUtils
				.getRequest().getSession().getAttribute("clientLoginBean"));
		if (clientLoginBean.isLogged()) {
			Client client = clientLoginBean.getClient();
			logTransactionToBase(client);
		}
	}

	public void logTransactionToBase(Client client) {
		Login login = new Login();
		login.setClient(client);
		login.setLogin_date(new Date());
		loginManager.saveLogin(login);

		Transaction transaction = new Transaction();
		transaction.setRealised(0);
		transaction.setLogin(login);
		transactionManager.saveTransaction(transaction);

		for (BookClient bookClient : getBook_list()) {
			TransactionBook transactionBook = new TransactionBook();
			transactionBook.setTransaction(transaction);
			transactionBook.setBook(bookClient.getBook());
			transactionBook.setBought_books(bookClient.getBooks_in_basket());
			transactionManager.saveTransactionBook(transactionBook);
		}

	}

	public void changeNumberOfBooks(ValueChangeEvent event) {
		createBookCookie();
	}
}